# -*- coding: utf-8 -*-
"""
@ Created on 2024-06-14 12:23
---------
@summary: 认证API路由
---------
@author: Lsaiah
"""

from fastapi import APIRouter, Depends, HTTPException, status, Form
from typing import Optional
from datetime import timedelta
from core.auth import AuthHandler
from core.response import ResponseModel, LoginResponseModel
from ..models.form import LoginRequest, RegisterRequest
from app.system.user.models.curd import UserCRUD
from constant import *
from log import logger
from settings import settings

auth_router = APIRouter(prefix="/system/auth", tags=["系统认证"])
auth_handler = AuthHandler()


@auth_router.post("/login", response_model=LoginResponseModel)
async def login(login_data: LoginRequest):
    """用户登录"""
    try:
        # 验证用户
        user = await UserCRUD.get_user_by_username(login_data.username)
        if not user:
            from datetime import datetime
            return LoginResponseModel(
                code=CODE_USER_NOT_FOUND,
                message=MESSAGE_USER_NOT_FOUND,
                data=None,
                timestamp=datetime.now().isoformat()
            )
        
        # 验证密码
        if not auth_handler.verify_password(login_data.password, user.hashed_password):
            from datetime import datetime
            return LoginResponseModel(
                code=CODE_USER_PASSWORD_ERROR,
                message=MESSAGE_USER_PASSWORD_ERROR,
                data=None,
                timestamp=datetime.now().isoformat()
            )
        
        # 检查用户状态
        if not user.is_active:
            from datetime import datetime
            return LoginResponseModel(
                code=CODE_USER_PASSWORD_ERROR,
                message=MESSAGE_USER_ACCOUNT_DISABLED,
                data=None,
                timestamp=datetime.now().isoformat()
            )
        
        # 创建访问令牌
        access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        access_token = auth_handler.create_access_token(
            data={"sub": str(user.id), "username": user.username},
            expires_delta=access_token_expires
        )
        
        # 更新最后登录时间
        await UserCRUD.update_last_login(user.id)
        
        # 构建用户信息
        user_info = {
            "id": user.id,
            "username": user.username,
            "email": user.email,
            "full_name": user.full_name,
            "is_active": user.is_active,
            "is_superuser": user.is_superuser
        }
        
        # 创建刷新令牌
        refresh_token = auth_handler.create_refresh_token(
            data={"sub": str(user.id), "username": user.username}
        )
        
        logger.info(f"用户登录成功: {user.username}")
        return LoginResponseModel.success(
            access_token=access_token,
            refresh_token=refresh_token,
            expires_in=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60,
            user_info=user_info
        )
        
    except Exception as e:
        logger.error(f"用户登录失败: {str(e)}")
        from datetime import datetime
        return LoginResponseModel(
            code=CODE_USER_LOGIN_FAILED,
            message=MESSAGE_USER_LOGIN_FAILED,
            data=None,
            timestamp=datetime.now().isoformat()
        )


@auth_router.post("/register", response_model=ResponseModel)
async def register(register_data: RegisterRequest):
    """用户注册"""
    try:
        # 检查用户名是否已存在
        existing_user = await UserCRUD.get_user_by_username(register_data.username)
        if existing_user:
            return ResponseModel.error(
                message=MESSAGE_USER_ALREADY_EXISTS,
                code=CODE_USER_ALREADY_EXISTS
            )
        
        # 加密密码
        hashed_password = auth_handler.get_password_hash(register_data.password)
        
        # 创建用户数据
        user_data = {
            "username": register_data.username, 
            "hashed_password": hashed_password,
            "email": register_data.email,
            "phone": register_data.phone,
            "full_name": register_data.full_name,
            "is_active": True,
            "is_superuser": False
        }
        
        # 创建用户
        user = await UserCRUD.create(user_data)
        
        logger.info(f"用户注册成功: {user.username}")
        return ResponseModel.success(
            data={"user_id": user.id, "username": user.username},
            message=MESSAGE_USER_REGISTER_SUCCESS,
            code=CODE_USER_REGISTER_SUCCESS
        )
        
    except Exception as e:
        logger.error(f"用户注册失败: {str(e)}")
        return ResponseModel.error(
            message=MESSAGE_USER_REGISTER_FAILED,
            code=CODE_USER_REGISTER_FAILED
        )


@auth_router.post("/refresh", response_model=ResponseModel)
async def refresh_token(refresh_token: str = Form(...)):
    """刷新访问令牌"""
    try:
        # 验证刷新令牌
        payload = auth_handler.verify_token(refresh_token)
        if not payload or payload.get("type") != "refresh":
            return ResponseModel.error(
                message="无效的刷新令牌",
                code=CODE_USER_TOKEN_INVALID
            )
        
        user_id = payload.get("sub")
        if not user_id:
            return ResponseModel.error(
                message="令牌中缺少用户ID",
                code=CODE_USER_TOKEN_INVALID
            )
        
        # 获取用户信息
        user = await UserCRUD.get_user_by_id(int(user_id))
        if not user or not user.is_active:
            return ResponseModel.error(
                message="用户不存在或已被禁用",
                code=CODE_USER_NOT_FOUND
            )
        
        # 创建新的访问令牌
        access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        access_token = auth_handler.create_access_token(
            data={"sub": str(user.id), "username": user.username},
            expires_delta=access_token_expires
        )
        
        return ResponseModel.success(
            data={
                "access_token": access_token,
                "token_type": "bearer",
                "expires_in": settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60
            },
            message="令牌刷新成功"
        )
        
    except Exception as e:
        logger.error(f"令牌刷新失败: {str(e)}")
        return ResponseModel.error(
            message="令牌刷新失败",
            code=CODE_ERROR
        )


@auth_router.post("/logout", response_model=ResponseModel)
async def logout(current_user = Depends(auth_handler.get_current_user)):
    """用户登出"""
    try:
        logger.info(f"用户登出: {current_user.username}")
        return ResponseModel.success(
            message=MESSAGE_USER_LOGOUT_SUCCESS,
            code=CODE_SUCCESS
        )
    except Exception as e:
        logger.error(f"用户登出失败: {str(e)}")
        return ResponseModel.error(
            message="登出失败",
            code=CODE_ERROR
        )


@auth_router.get("/me", response_model=ResponseModel)
async def get_current_user_info(current_user = Depends(auth_handler.get_current_user)):
    """获取当前用户信息"""
    try:
        user_info = {
            "id": current_user.id,
            "username": current_user.username,
            "email": current_user.email,
            "full_name": current_user.full_name,
            "is_active": current_user.is_active,
            "is_superuser": current_user.is_superuser,
            "last_login": current_user.last_login.isoformat() if current_user.last_login else None,
            "created_at": current_user.created_at.isoformat(),
            "updated_at": current_user.updated_at.isoformat()
        }
        
        return ResponseModel.success(
            data=user_info,
            message=MESSAGE_SUCCESS
        )
    except Exception as e:
        logger.error(f"获取用户信息失败: {str(e)}")
        return ResponseModel.error(
            message="获取用户信息失败",
            code=CODE_ERROR
        )
